package com.xplusplus.security.controller;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.xplusplus.security.domain.*;
import com.xplusplus.security.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import com.xplusplus.security.service.ProjectUserService;
import com.xplusplus.security.service.UserService;
import com.xplusplus.security.utils.ResultUtil;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Author: zhouweixin
 * @Description:
 * @Date: Created in 20:37 2018/5/7
 * @Modified By:
 */
@RestController
@RequestMapping(value = "/user")
@Api(tags = "用户接口")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private ProjectUserService projectUserService;

    /**
     * 新增
     *
     * @param user
     * @return
     */
    @RequestMapping(value = "/add")
    public Result<User> add(@Valid User user, BindingResult bindingResult) {

        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getFieldError().getDefaultMessage().toString());
        }

        return ResultUtil.success(userService.save(user));
    }

    /**
     * 更新
     *
     * @param user
     * @return
     */
    @RequestMapping(value = "/update")
    public Result<User> update(@Valid User user, BindingResult bindingResult) {

        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getFieldError().getDefaultMessage().toString());
        }

        return ResultUtil.success(userService.update(user));
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/deleteById")
    public Result<Object> deleteById(String id) {
        userService.delete(id);
        return ResultUtil.success();
    }

    /**
     * 批量删除
     *
     * @param users
     * @return
     */
    @RequestMapping(value = "/deleteByIdBatch")
    public Result<Object> deleteByIdBatch(@RequestBody Collection<User> users) {
        userService.deleteInBatch(users);
        return ResultUtil.success();
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/getById")
    public Result<User> getById(String id) {
        return ResultUtil.success(userService.findOne(id));
    }

    /**
     * 查询所有
     *
     * @return
     */
    @RequestMapping(value = "/getAll")
    public Result<List<User>> getAll() {
        return ResultUtil.success(userService.findAll());
    }

    /**
     * 查询所有-分页
     *
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    @RequestMapping(value = "/getAllByPage")
    public Result<Page<User>> getAllByPage(@RequestParam(value = "page", defaultValue = "0") Integer page,
                                           @RequestParam(value = "size", defaultValue = "10") Integer size,
                                           @RequestParam(value = "sortFieldName", defaultValue = "id") String sortFieldName,
                                           @RequestParam(value = "asc", defaultValue = "1") Integer asc) {

        return ResultUtil.success(userService.findAllByPage(page, size, sortFieldName, asc));
    }

    /**
     * 通过名称模糊查询
     *
     * @param name
     * @return
     */
    @RequestMapping(value = "/getByNameLike")
    public Result<List<User>> getByNameLike(@RequestParam(value = "name", defaultValue = "") String name) {
        return ResultUtil.success(userService.findByNameLike(name));
    }

    /**
     * 通过名称模糊查询-分页
     *
     * @param name
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    @RequestMapping(value = "/getByNameLikeByPage")
    public Result<Page<User>> getByNameLikeByPage(@RequestParam(value = "name", defaultValue = "") String name,
                                                  @RequestParam(value = "page", defaultValue = "0") Integer page,
                                                  @RequestParam(value = "size", defaultValue = "10") Integer size,
                                                  @RequestParam(value = "sortFieldName", defaultValue = "id") String sortFieldName,
                                                  @RequestParam(value = "asc", defaultValue = "1") Integer asc) {

        return ResultUtil.success(userService.findByNameLikeByPage(name, page, size, sortFieldName, asc));
    }

    /**
     * 通过部门, 用户名，工号或ic卡号模糊查询-分页
     *
     * @param departmentId  部门主键
     * @param type          0姓名；1工号；2ic卡（默认为0）
     * @param keyword       关键字
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    @RequestMapping(value = "/searchByPage")
    public Result<Page<User>> searchByPage(
            @RequestParam(defaultValue = "-1") int departmentId,
            @RequestParam(value = "type", defaultValue = "0") int type,
            @RequestParam(value = "keyword", defaultValue = "") String keyword,
            @RequestParam(value = "page", defaultValue = "0") Integer page,
            @RequestParam(value = "size", defaultValue = "10") Integer size,
            @RequestParam(value = "sortFieldName", defaultValue = "id") String sortFieldName,
            @RequestParam(value = "asc", defaultValue = "1") Integer asc) {

        return ResultUtil.success(userService.searchByPage(departmentId, type, keyword, page, size, sortFieldName, asc));
    }

    @GetMapping(value = "/mulSearchByPage")
    @ApiOperation(value = "多条件查询")
    public Result<Page<User>> mulSearchByPage(
            @ApiParam(defaultValue = "-1") @RequestParam(defaultValue = "-1") int departmentId,
            @ApiParam(defaultValue = "-1") @RequestParam(defaultValue = "-1") int militaryStatusId,
            @ApiParam(defaultValue = "-1") @RequestParam(defaultValue = "-1") int hasSecuCert,
            @ApiParam(defaultValue = "-1") @RequestParam(defaultValue = "-1") int sex,
            @ApiParam(defaultValue = "-1") @RequestParam(defaultValue = "-1") int age,
            @ApiParam(defaultValue = "") @RequestParam(defaultValue = "") String projectName,
            @ApiParam(defaultValue = "0") @RequestParam(value = "type", defaultValue = "0") int type,
            @ApiParam(defaultValue = "") @RequestParam(value = "keyword", defaultValue = "") String keyword,
            @ApiParam(defaultValue = "0") @RequestParam(value = "page", defaultValue = "0") int page,
            @ApiParam(defaultValue = "10") @RequestParam(value = "size", defaultValue = "10") int size,
            @ApiParam(defaultValue = "id") @RequestParam(value = "sortFieldName", defaultValue = "id") String sortFieldName,
            @ApiParam(defaultValue = "1") @RequestParam(value = "asc", defaultValue = "1") int asc) {

        return ResultUtil.success(userService.mulSearchByPage(departmentId, projectName, militaryStatusId, hasSecuCert, sex, age, type, keyword, page, size, sortFieldName, asc));
    }

    @GetMapping(value = "/mulSearchExport")
    @ApiOperation(value = "多条件导出")
    public Result<Object> mulSearchExport(
            @ApiParam(defaultValue = "-1") @RequestParam(defaultValue = "-1") int departmentId,
            @ApiParam(defaultValue = "-1") @RequestParam(defaultValue = "-1") int militaryStatusId,
            @ApiParam(defaultValue = "-1") @RequestParam(defaultValue = "-1") int hasSecuCert,
            @ApiParam(defaultValue = "-1") @RequestParam(defaultValue = "-1") int sex,
            @ApiParam(defaultValue = "-1") @RequestParam(defaultValue = "-1") int age,
            @ApiParam(defaultValue = "") @RequestParam(defaultValue = "") String projectName,
            @ApiParam(defaultValue = "0") @RequestParam(value = "type", defaultValue = "0") int type,
            @ApiParam(defaultValue = "") @RequestParam(value = "keyword", defaultValue = "") String keyword,
            HttpServletResponse response) throws IOException {

        List<User> users = userService.mulSearchExport(departmentId, projectName, militaryStatusId, hasSecuCert, sex, age, type, keyword);

        String fileName = "徐州精诚特卫员工列表.xlsx";
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("徐州精诚特卫员工列表","员工", ExcelType.XSSF), User.class, users);
        response.addHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
        response.flushBuffer();
        workbook.write(response.getOutputStream());
        return ResultUtil.success();
    }

    /**
     * 通过用户名，工号或ic卡号模糊查询-分页
     *
     * @param type    0姓名；1工号；2ic卡（默认为0）
     * @param keyword 关键字
     * @return
     */
    @RequestMapping(value = "/search")
    public Result<List<User>> searchByPage(@RequestParam(value = "type", defaultValue = "0") int type,
                                           @RequestParam(value = "keyword", defaultValue = "") String keyword) {

        return ResultUtil.success(userService.search(type, keyword));
    }

    /**
     * 通过部门查询
     *
     * @param department
     * @return
     */
    @RequestMapping(value = "/getByDepartment")
    public Result<List<User>> getByDepartment(Department department) {
        return ResultUtil.success(userService.findByDepartment(department));
    }

    /**
     * 通过项目查询
     *
     * @param project
     * @return
     */
    @RequestMapping(value = "/getByProject")
    public Result<List<ProjectUser>> getByProject(Project project) {
        return ResultUtil.success(projectUserService.findByProject(project));
    }

    /**
     * 通过部门和名称模糊查询-分页
     *
     * @param name
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    @RequestMapping(value = "/getByDepartmentAndNameLikeByPage")
    public Result<Page<User>> getByDepartmentAndNameLikeByPage(@RequestParam(defaultValue = "-1") int id,
                                                               @RequestParam(value = "name", defaultValue = "") String name,
                                                               @RequestParam(value = "page", defaultValue = "0") Integer page,
                                                               @RequestParam(value = "size", defaultValue = "10") Integer size,
                                                               @RequestParam(value = "sortFieldName", defaultValue = "id") String sortFieldName,
                                                               @RequestParam(value = "asc", defaultValue = "1") Integer asc) {
        return ResultUtil.success(userService.findByDepartmentAndNameLikeByPage(id, name, page, size, sortFieldName, asc));
    }
    /**
     * 通过部门和名称模糊查询-分页
     *
     * @param keyword
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    @RequestMapping(value = "/getByDepartmentAndKeywordLikeByPage")
    public Result<Page<User>> getByDepartmentAndKeywordLikeByPage(@RequestParam(defaultValue = "-1") int id,
                                                                  @RequestParam(defaultValue = "0") int type,
                                                                  @RequestParam(defaultValue = "") String keyword,
                                                                  @RequestParam(value = "page", defaultValue = "0") Integer page,
                                                                  @RequestParam(value = "size", defaultValue = "10") Integer size,
                                                                  @RequestParam(value = "sortFieldName", defaultValue = "id") String sortFieldName,
                                                                  @RequestParam(value = "asc", defaultValue = "1") Integer asc) {

        return ResultUtil.success(userService.findByDepartmentAndKeywordLikeByPage(id, type, keyword, page, size, sortFieldName, asc));
    }

    /**
     * 通过工作性质，部门，类型和关键字查询-分页
     *
     * @param jobNatureId
     * @param departmentId
     * @param type          类型：0姓名；1工号；2IC号
     * @param keyword
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    @RequestMapping(value = "/getByJobNatureAndDepartmentAndTypeAndKeywordByPage")
    public Result<Page<User>> getByJobNatureAndDepartmentAndTypeAndKeywordByPage(@RequestParam(defaultValue = "-1") int jobNatureId,
                                                                                 @RequestParam(defaultValue = "-1") int departmentId,
                                                                                 @RequestParam(defaultValue = "0") int type,
                                                                                 @RequestParam(value = "keyword", defaultValue = "") String keyword,
                                                                                 @RequestParam(value = "page", defaultValue = "0") Integer page,
                                                                                 @RequestParam(value = "size", defaultValue = "10") Integer size,
                                                                                 @RequestParam(value = "sortFieldName", defaultValue = "id") String sortFieldName,
                                                                                 @RequestParam(value = "asc", defaultValue = "1") Integer asc) {

        return ResultUtil.success(userService.getByJobNatureAndDepartmentAndTypeAndKeywordByPage(jobNatureId, departmentId, type, keyword, page, size, sortFieldName, asc));
    }

    /**
     * 通过工作性质查询
     *
     * @param jobNature
     * @return
     */
    @RequestMapping(value = "/getByJobNature")
    public Result<List<User>> getByJobNature(JobNature jobNature) {
        return ResultUtil.success(userService.findByJobNature(jobNature));
    }

    /**
     * 通过工作性质查询-分页
     *
     * @param jobNature
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    @RequestMapping(value = "/getByJobNatureByPage")
    public Result<Page<User>> getByJobNatureByPage(JobNature jobNature,
                                                   @RequestParam(value = "page", defaultValue = "0") Integer page,
                                                   @RequestParam(value = "size", defaultValue = "10") Integer size,
                                                   @RequestParam(value = "sortFieldName", defaultValue = "id") String sortFieldName,
                                                   @RequestParam(value = "asc", defaultValue = "1") Integer asc) {

        return ResultUtil.success(userService.findByJobNatureByPage(jobNature, page, size, sortFieldName, asc));
    }

    /**
     * 通过id更新工作性质
     *
     * @param jobNatureId
     * @param id
     * @return
     */
    @RequestMapping(value = "/updateJobNatureById")
    public Result<Object> updateJobNatureById(Integer jobNatureId, String id) {
        userService.updateJobNatureById(jobNatureId, id);
        return ResultUtil.success();
    }

    /**
     * 离职
     *
     * @return
     */
    @RequestMapping(value = "/resign")
    public Result<Object> resign(@DateTimeFormat(pattern = "yyyy-MM-dd") Date resignDate,
                                 @RequestParam(value = "resignTypeId", defaultValue = "-1") Integer resignTypeId,
                                 @RequestParam(value = "id", defaultValue = "-1") String id) {
        userService.updateResignDateAndResignType(resignDate, resignTypeId, id);
        return ResultUtil.success();
    }

    /**
     * 通过主键更新ic卡号
     *
     * @param id
     * @param ic
     */
    @RequestMapping(value = "/updateIcById")
    public Result<Object> updateIcById(String id, String ic) {
        userService.updateIcById(id, ic);
        return ResultUtil.success();
    }

    /**
     * 统计男女人数
     *
     * @return
     */
    @RequestMapping(value = "/getUserNumber")
    public Result<UserNumberVO> getUserNumber() {
        return ResultUtil.success(userService.findUserNumber());
    }

    /**
     * 统计不同年龄段的人数
     *
     * @return
     */
    @RequestMapping(value = "/getUserNumberByPage")
    public Result<UserAgeNumberVO> getUserNumberByPage() {
        return ResultUtil.success(userService.getUserNumberByPage());
    }

    /**
     * 统计不同项目的人数
     *
     * @return
     */
    @RequestMapping(value = "/getUserNumberByProject")
    public Result<List<UserProjectNumberVO>> getUserNumberByProject() {
        return ResultUtil.success(userService.getUserNumberByProject());
    }

    /**
     * 统计不同学历的人数
     *
     * @return
     */
    @RequestMapping(value = "/getUserNumberByEducation")
    public Result<List<UserEducationNumberVO>> getUserNumberByEducation() {
        return ResultUtil.success(userService.getUserNumberByEducation());
    }

    /**
     * 统计某天不同项目参加考勤的人数
     *
     * @return
     */
    @RequestMapping(value = "/getUserNumberByProjectAttenAndDate")
    public Result<List<UserProjectAttendanceNumberVO>> getUserNumberByProjectAttenAndDate(
            @RequestParam(defaultValue = "1970-01-01") @DateTimeFormat(pattern = "yyyy-MM-dd") Date date) {

        if (new SimpleDateFormat("yyyy-MM-dd").format(date).equals("1970-01-01")) {
            return ResultUtil.success(userService.getUserNumberByProjectAttenAndDate(new Date()));
        }

        return ResultUtil.success(userService.getUserNumberByProjectAttenAndDate(date));
    }

    /**
     * 批量更新用户的基本工资，社保，基金和岗位津贴
     *
     * @return
     */
    @RequestMapping(value = "/updateWagesByIds")
    public Result<Object> updateWageByIds(String[] userIds,
                                          @RequestParam(defaultValue = "-1") double base,
                                          @RequestParam(defaultValue = "-1") double socialSecurity,
                                          @RequestParam(defaultValue = "-1") double foundation,
                                          @RequestParam(defaultValue = "-1") double postAllowance) {
        userService.updateWageByIds(userIds, base, socialSecurity, foundation, postAllowance);
        return ResultUtil.success();
    }

    @PostMapping(value = "/login")
    @ApiOperation(value = "登录")
    public Result<User> login(String id, String password, HttpSession session) {
        return ResultUtil.success(userService.login(id, password, session));
    }

    @GetMapping(value = "/logout")
    @ApiOperation(value = "注销")
    public Result<Object> logout(HttpSession session) {
        session.removeAttribute("user");
        return ResultUtil.success();
    }

    /**
     * 上传文件
     *
     * @param file
     * @return
     */
    @PostMapping(value = "/importUsersFromExcel")
    @ApiOperation(value = "从excel文件导入员工")
    public Result<Object> importUsersFromExcel(@RequestParam("file") MultipartFile file) {
        userService.importExcel(file);
        return ResultUtil.success();
    }

    @GetMapping(value = "/cancelImport")
    @ApiOperation(value = "取消导入员工")
    public Result<Object> cancelImport() {
        userService.cancelImport();
        return ResultUtil.success();
    }

    @PostMapping(value = "/updateProjectName")
    @ApiOperation(value = "更新当前项目名称")
    public Result<Object> updateProjectName(@RequestParam String name, @RequestParam String id){
        userService.updateProjectName(name, id);
        return ResultUtil.success();
    }

    @PostMapping(value = "/updatePassword")
    @ApiOperation(value = "修改密码")
    public Result<Page<User>> updatePassword(
            @ApiParam(value = "用户主键") @RequestParam String id,
            @ApiParam(value = "旧密码") @RequestParam(value = "oldPassword") String oldPassword,
            @ApiParam(value = "新密码") @RequestParam(value = "newPassword") String newPassword,
            @ApiParam(value = "重复新密码") @RequestParam(value = "reNewPassword") String reNewPassword) {
        userService.updatePassword(id, oldPassword, newPassword, reNewPassword);
        return ResultUtil.success();
    }

    @PostMapping(value = "/updateProject")
    @ApiOperation(value = "修改用户所在项目")
    public Result<Object> updateProject(
            @ApiParam(value = "用户主键") @RequestParam String userId,
            @ApiParam(value = "项目主键") @RequestParam Long projectId){
        projectUserService.updateUserProject(userId, projectId);
        return ResultUtil.success();
    }
}
